/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package facade;
import AlgoritmoPronostico.Algoritmo;
import AlgoritmoPronostico.Parametros;
import beans.Mapa;
import AlgoritmoPronostico.Reloj;
import AlgoritmoPronostico.Despachador;
import beans.Pedido;
import colonia.ColoniaHormigas;
import AlgoritmoPronostico.GestorVehiculos;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import pronostico.Pronostico;
import response.InformePronostico;

/**
 *
 * @author Ahmed
 */
public class PronosticoFacade implements Runnable{
    
    public static boolean falloPronostico = false;
    public static PronosticoFacade _pronosticoFacade;
    public static final int ventana = 8;
    public static ArrayList<Pedido> pedidos = new ArrayList<>();
    private ServletContext servletContext;
    public boolean colapso = false;
    private boolean running=false;
    private Thread pronostico;
    
    public synchronized static PronosticoFacade getInstancia(){
        if (_pronosticoFacade == null)
            _pronosticoFacade = new PronosticoFacade();
        return _pronosticoFacade;
    }
        private boolean _stopped = false;
    
    public synchronized void runSimulation(){
        if (running) return;
        running=true;
        pronostico = new Thread(this);
        pronostico.start();
        
    }
    
    public static void PronosticoFacade(){
        PronosticoFacade pF = PronosticoFacade.getInstancia();
        pF.runSimulation();
    }
    
    public ServletContext getServletContext() {
        return servletContext;
    }
    
    @Override
    public void run(){
        //Pronostico pronostico = new Pronostico();
        Pronostico.generarArchivos();
        Parametros.init();
        Mapa.init(Parametros.ANCHO_MAPA, Parametros.ALTO_MAPA, " ");
        Reloj reloj = Reloj.getInstancia();
        GestorVehiculos gestorVehiculos = GestorVehiculos.getInstancia();
        gestorVehiculos.crearVehiculos();
        ColoniaHormigas.crearNodosMapa(); 
        ColoniaHormigas.initFeronoma();
        reloj.setReloj(0, 0, 18, 6, 2013);
        Despachador.leerEventosDia("18","06","2013");
        Calendar proxDia = (Calendar)reloj.getFecha().clone();
        proxDia.add(Calendar.DAY_OF_MONTH, 1);
        pedidos = Despachador.siguientesPedidos(reloj.getHora(),reloj.getMinuto());
        Calendar proxVentana = (Calendar)reloj.getFecha().clone();
        proxVentana.add(Calendar.MINUTE, ventana);
        boolean hayDia = false; 
        ArrayList<Pedido> pedidosNuevos;
        reloj.iniciar();
        Calendar fechaAux;
        ArrayList<Pedido> pedidosVencidos = new ArrayList<>();
        gestorVehiculos.actualizaTurno();
        while (true) {
            if (_stopped) break;
            if(proxVentana.after(fechaAux = (Calendar)reloj.getFecha().clone()))continue;
            fechaAux = (Calendar)proxVentana.clone();
            proxVentana.add(Calendar.MINUTE, ventana);
            reloj.pausar();
            reloj.setFecha((Calendar) fechaAux.clone());
            for(int o=0; o < pedidos.size();o++){
                if (pedidosVencidos.contains(pedidos.get(o))) continue;
                    if (pedidos.get(o).getFechaVencimiento().before(reloj.getFecha())) {
//                        pedidosVencidos.add(pedidos.get(o));
                        System.out.println("Tarde " + reloj.getFechaString("dd/MM/yyy HH:mm")+" Pedido: " + pedidos.get(o).getIdPedido() + " vence: " + pedidos.get(o).getFechaString(pedidos.get(o).getFechaVencimiento(), "dd/MM/yyy HH:mm")+" X = "+pedidos.get(o).getDestino().getX()+", Y = "+pedidos.get(o).getDestino().getY());
                        InformePronostico infPro = InformePronostico.getInstancia();
                        infPro.setFecha(reloj.getFechaString("dd/MM/yyy"));
                        if(reloj.getHora() <=7) infPro.setTurno(1);
                        if(reloj.getHora() <=15 && reloj.getHora()>7) infPro.setTurno(2);
                        if(reloj.getHora() <=23 && reloj.getHora()>15) infPro.setTurno(2);
                        infPro.setHora(reloj.getFechaString("HH:mm"));
                        reloj.detener();
                        _stopped = true;
                        continue;
                    }
            }
            ColoniaHormigas.obtenerSolucionInversa2(pedidos);
            //System.out.println(a.getTime() - b.getTime());
            gestorVehiculos.asignarRutas(ColoniaHormigas.mejoresHormigas,ColoniaHormigas.pedidosAsignados);
            gestorVehiculos.actualizarVehiculosYOrdenes(ventana, pedidos);
            if(proxDia.compareTo(reloj.getFecha())<=0){
                proxDia = (Calendar)reloj.getFecha().clone();
                proxDia.add(Calendar.DAY_OF_MONTH, 1);
                String dia = reloj.getFechaString("dd");
                String mes = reloj.getFechaString("MM");
                String anho = reloj.getFechaString("yyyy");
                hayDia = Despachador.leerEventosDia(dia,mes,anho);
                if(!hayDia){
                    reloj.detener();
                    break;
                }
            }
            pedidosNuevos = Despachador.siguientesPedidos(reloj.getHora(),reloj.getMinuto());
            pedidos.addAll(pedidosNuevos);
            reloj.continuar();
        }
        //reloj.detener();
        try {
            PedidosFacade.pronostico(Despachador.pedidos_x_dia,Despachador.paquetes_x_dia);
        } catch (SQLException ex) {}
        falloPronostico = true;
    }
    
    public boolean isRunning() {
        return running;
    }
    
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }
    
    public void seguirSimulacion(){
        this._stopped = false;       
    }
    
}
